/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/



#if !defined(AFX_PGLCOLOR_H__4DACBB75_9EFC_11D4_8A95_D4B14EEC3D7F__INCLUDED_)
#define AFX_PGLCOLOR_H__4DACBB75_9EFC_11D4_8A95_D4B14EEC3D7F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CPGLArchive;

/*!
	\defgroup PGLBasicGroup Miscellanous
	\ingroup PGLCoreGroup
*/

/*! \brief A simple RGBA color object.

\ingroup PGLBasicGroup
This object represent a RGAB color. All values for colors must be in [0,1].
*/
class PGLCORE_EXT_CLASS CPGLColor  : public CObject
{
public:
	DECLARE_DYNCREATE(CPGLColor);

	//! \name Constructors
	//@{
	/// a constructor
	CPGLColor(float red=0.0f, float green=0.0f, float blue=0.0f, float alpha=1.0f)
	{	m_c[0]=(float)__max(0.0f,__min(1.0f,red)); 
		m_c[1]=(float)__max(0.0f,__min(1.0f,green)); 
		m_c[2]=(float)__max(0.0f,__min(1.0f,blue)); 
		m_c[3]=(float)__max(0.0f,__min(1.0f,alpha));
	};
	/// a constructor
	CPGLColor(float _c[4])
	{	m_c[0]=(float)__max(0.0f,__min(1.0f,_c[0])); 
		m_c[1]=(float)__max(0.0f,__min(1.0f,_c[1])); 
		m_c[2]=(float)__max(0.0f,__min(1.0f,_c[2])); 
		m_c[3]=(float)__max(0.0f,__min(1.0f,_c[3]));
	};
	/// copy constructor
		CPGLColor(const CPGLColor& col){*this=col;};
	/// assignement constructor
	CPGLColor& operator = (const CPGLColor& col)
	{	// prevent self-assignement
		if (&col != this)
		{	m_c[0]=col.m_c[0];
			m_c[1]=col.m_c[1];
			m_c[2]=col.m_c[2];
			m_c[3]=col.m_c[3];}
		return *this;};

	/// destructor
	virtual ~CPGLColor(){};
	//@}

	//! \name Setters and getters
	//@{
	/// sets a new color
	void SetColor(float _c[4]) 
	{	m_c[0]=(float)__max(0.0,__min(1.0f,_c[0])); 
		m_c[1]=(float)__max(0.0,__min(1.0f,_c[1]));
		m_c[2]=(float)__max(0.0,__min(1.0f,_c[2]));
		m_c[3]=(float)__max(0.0,__min(1.0f,_c[3])); };
	///sets the color
	void SetColor(float red,float green,float blue,float alpha=1.0f)	{	m_c[0]=(float)__max(0.0,__min(1.0f,red)); m_c[1]=(float)__max(0.0,__min(1.0f,green)); m_c[2]=(float)__max(0.0,__min(1.0f,blue)); m_c[3]=(float)__max(0.0,__min(1.0f,alpha)); };
	/// sets the red component of color (must be in [0, 1])
		void SetRed(float f)											{	m_c[0]=__max(0,__min(1,f));};
	/// sets the green component of color (must be in [0, 1])
	void SetGreen(float f)												{	m_c[1]=__max(0,__min(1,f));};
	/// sets the blue component of color (must be in [0, 1])
	void SetBlue(float f)												{	m_c[2]=__max(0,__min(1,f));};
	/// sets the alpha component of color (must be in [0, 1])
	void SetAlpha(float f)												{	m_c[3]=__max(0,__min(1,f));};
	/// getting color component (c must of size >=4)
	void GetColor(float *_c) const										{	_c[0]=m_c[0]; _c[1]=m_c[1];_c[2]=m_c[2];_c[3]=m_c[3]; };
	/// gets red component
	float GetRed()	const												{ return m_c[0];}; 
	/// gets green component
	float GetGreen()	const											{ return m_c[1];};
	/// gets blue component
	float GetBlue()const												{ return m_c[2];};
	/// gets alpha component
	float GetAlpha()const												{ return m_c[3];};
	/// gets color component (0 for red, 1 for green, 2 for blue and 3 for alpha)
	float operator [] (int i) const										{ ASSERT(i>=0 && i<4); return m_c[i];};
	/// gets a reference to color component (0 for red, 1 for green, 2 for blue and 3 for alpha)
	float& operator [] (int i)											{ ASSERT(i>=0 && i<4); return m_c[i];};
	gfxinterface::SRGBA GetRGBA() const									{	gfxinterface::SRGBA rgba; rgba.r=m_c[0];rgba.g=m_c[1];rgba.b=m_c[2];rgba.a=m_c[3]; return rgba;};
	//@}

	//! \name Predefined colors
	//@{
	enum EColor
	{
		AliceBlue,
		AntiqueWhite,
		Aqua,
		Aquamarine,
		Azure,
		Beige,
		Bisque,
		Black,
		BlancheDalmond,
		Blue,
		BlueViolet,
		Brown,
		BurlyWood,
		CadetBlue,
		Chartreuse,
		Chocolate,
		Coral,
		CornFlowerBlue,
		CornSilk,
		Crimson,
		Cyan,
		DarkBlue,
		DarkCyan,
		DarkGoldenRod,
		DarkGray,
		DarkGreen,
		DarkKhaki,
		DarkMagenta,
		DarkOliveGreen,
		DarkOrange,
		DarkOrchid,
		DarkRed,
		DarkSalmon,
		DarkSeaGreen,
		DarkSlateBlue,
		DarkSlateGray,
		DarkTurquoise,
		DarkViolet,
		DeepPink,
		DeepSkyBlue,
		DimGray,
		DodgerBlue,
		FireBrick,
		FloralWhite,
		ForestGreen,
		Fuchsia,
		Gainsboro,
		GhostWhite,
		Gold,
		GoldenRod,
		Gray,
		Green,
		GreenYellow,
		HoneyDew,
		HotPink,
		IndianRed,
		Indigo,
		Ivory,
		Khaki,
		Lavender,
		LavenderBlush,
		LawnGreen,
		LemonChiffon,
		LightBlue,
		LightCoral,
		LightCyan,
		LightGoldenRodYellow,
		LightGreen,
		LightGrey,
		LightPink,
		LightSalmon,
		LightSeaGreen,
		LightSkyBlue,
		LightSlateGray,
		LightSteelBlue,
		LightYellow,
		Lime,
		LimeGreen,
		Linen,
		Magenta,
		Maroon,
		MediumAquaMarine,
		MediumBlue,
		MediumOrchid,
		MediumPurple,
		MediumSeaGreen,
		MediumSlateBlue,
		MediumSpringGreen,
		MediumTurquoise,
		MediumVioletRed,
		MidnightBlue,
		MintCream,
		MistyRose,
		Moccasin,
		NavajoWhite,
		Navy,
		OldLace,
		Olive,
		OliveDrab,
		Orange,
		OrangeRed,
		Orchid,
		PaleGoldenRod,
		PaleGreen,
		PaleTurquoise,
		PaleVioletRed,
		PapayaWhip,
		PeachPuff,
		Peru,
		Pink,
		Plum,
		PowderBlue,
		Purple,
		Red,
		RosyBrown,
		RoyalBlue,
		SaddleBrown,
		Salmon,
		SandyBrown,
		SeaGreen,
		SeaShell,
		Sienna,
		Silver,
		SkyBlue,
		SlateBlue,
		SlateGray,
		Snow,
		SpringGreen,
		SteelBlue,
		Tan,
		Teal,
		Thistle,
		Tomato,
		Turquoise,
		Violet,
		Wheat,
		White,
		WhiteSmoke,
		Yellow,
		YellowGreen
	};
	static CPGLColor GetClassicColor( EColor eColor, float fAlpha = 1);
	static CPGLColor NextClassicColor();
	static void PrepareClassicColors();
	typedef std::map< CString , EColor > ClassicColorMap;
	const ClassicColorMap& GetClassics()  {	return m_mClassics;};
	static CPGLColor StringToColor( LPCTSTR szColor ); 
	//@}


	//! \name GfxInterface methods
	//@{
	void MakeCurrent(gfxinterface::CGfxInterface& gfx)		{	gfx.SetColor(m_c[0],m_c[1],m_c[2],m_c[3]);};
	void MakeCurrentFill(gfxinterface::CGfxInterface& gfx)	{	gfx.SetFillColor(m_c[0],m_c[1],m_c[2],m_c[3]);};
	//@}

	//! \name Serialize functions
	//@{
	//! Save settings in XML
	void SerializeXML( CPGLArchive& ar);

	/// Debuggin functions
	#ifdef _DEBUG
	    virtual void Dump( CDumpContext& dc ) const;
	    virtual void AssertValid() const;    // Override
	#endif
	//@}
protected:
	//! \name Class Parameters
	//@{
	/// the color
	float m_c[4];
	//@}
private:
	static ClassicColorMap m_mClassics;
};



#endif // !defined(AFX_PGLCOLOR_H__4DACBB75_9EFC_11D4_8A95_D4B14EEC3D7F__INCLUDED_)
